/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.common.base.office.service;

import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson2.JSONObject;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.je.common.base.DynaBean;
import com.je.common.base.document.InternalFileBO;
import com.je.common.base.office.util.OfficeUtil;
import com.je.common.base.office.vo.JeOfficeVo;
import com.je.common.base.office.vo.JePdfVo;
import com.je.common.base.office.vo.OfficeDataVo;
import com.je.common.base.service.rpc.DocumentInternalRpcService;
import com.je.common.base.util.DateUtils;
import com.je.common.base.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.*;

@Component("jePdfService")
public class JePdfServiceImpl implements JePdfService {
    @Autowired
    private DocumentInternalRpcService documentInternalRpcService;
    @Autowired
    private JeOfficeService jeOfficeService;
    @Override
    public void doExecOffice(JeOfficeVo jeOfficeVo, JSONObject returnObj) {
        String fileKey=OfficeUtil.getFileKey(jeOfficeVo.getFile());
        if(StringUtil.isEmpty(fileKey)){
            returnObj.put("success",false);
            returnObj.put("obj","模版文件未上传");
        }
        JePdfVo jePdfVo=new JePdfVo();
        InternalFileBO fileBO=documentInternalRpcService.selectFileByKey(fileKey);
        File file=documentInternalRpcService.readFile(fileKey);
        FileInputStream fileIo=null;
        jeOfficeVo.setFileContextType(fileBO.getContentType());
        if(!file.exists()){
            returnObj.put("success",false);
            returnObj.put("obj","模版文件不存在!");
            return;
        }
        try {
            fileIo=new FileInputStream(file);
            PdfReader reader = new PdfReader(fileIo);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            PdfStamper stamper = new PdfStamper(reader, outputStream);
            //解析中文
            BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            AcroFields form = stamper.getAcroFields();
            form.addSubstitutionFont(bf);
            jePdfVo.setReader(reader);
            jePdfVo.setPdfStamper(stamper);
            jePdfVo.setForm(form);
            jeOfficeVo.setJePdfVo(jePdfVo);
            //执行事件
            jeOfficeService.doExecEvent(jeOfficeVo,"before");
            //得到所有字段名
            Map<String, AcroFields.Item> fields = form.getFields();
            for(String key:fields.keySet()){
                if(key.startsWith("{") && key.endsWith("}")){
                    form.setField(key, parseFieldValue(key,jeOfficeVo));
                }
            }
            jeOfficeService.doExecEvent(jeOfficeVo,"after");
            //得到业务对象
            stamper.setFormFlattening(true);
            stamper.close();
            reader.close();
            //输出转输入
            byte[] filebytes=outputStream.toByteArray();
            jeOfficeVo.setFileSize(new Long(filebytes.length));
            ByteArrayInputStream inputStream = IoUtil.toStream(filebytes);
            //关闭ExcelWriter outputStream
            IoUtil.close(outputStream);
            IoUtil.close(fileIo);
            jeOfficeVo.setInputStream(inputStream);
            returnObj.put("success",true);
            returnObj.put("obj","操作成功!");
        }catch (Exception e){
            e.printStackTrace();
            returnObj.put("success",false);
            returnObj.put("obj","系统导出出错了，请联系管理员!");
        }
    }
    private String parseFieldValue(String key,JeOfficeVo jeOfficeVo){
        String fieldStr=key.substring(1,key.length()-1);
        String dsCode="";
        String fieldCode="";
        if(fieldStr.split("\\.").length==2){
            dsCode=fieldStr.split("\\.")[0];
            fieldCode=fieldStr.split("\\.")[1];
        }else if(jeOfficeVo.getOfficeDatas().size()==1){
            dsCode=jeOfficeVo.getOfficeDatas().get(0).getCode();
            fieldCode=fieldStr;
        }
        OfficeDataVo officeDataVo=jeOfficeVo.getOfficeDataVo(dsCode);
        DynaBean fieldInfo=officeDataVo.getField(fieldCode);
        String value="";//默认值
        if("bean".equals(officeDataVo.getType())){
            value=getFieldValue(officeDataVo.getDynaBean(),fieldInfo);
        }else{
            List<DynaBean> lists=officeDataVo.getLists();
            DynaBean useBean=new DynaBean();
            if(lists.size()>0){
                useBean=lists.get(0);
            }
            value=getFieldValue(useBean,fieldInfo);
//            value=StringUtil.buildSplitString(ArrayUtils.getBeanFieldArray(lists,fieldCode),",");
        }
        return value;
    }
    public String getFieldValue(DynaBean dynaBean, DynaBean fieldInfo){
        String fieldCode=fieldInfo.getStr("FIELD_CODE");
        String fieldType=fieldInfo.getStr("FIELD_TYPE");
        String configInfo=fieldInfo.getStr("FIELD_CONFIGINFO");
        String value=dynaBean.getStr(fieldCode);
        if("DATE".equals(fieldType)){
            if(StringUtil.isNotEmpty(fieldInfo.getStr("FIELD_CONFIGINFO")) && StringUtil.isNotEmpty(value)){
                Date d= DateUtils.getDate(value, DateUtils.DAFAULT_DATE_FORMAT);
                if(d!=null) {
                    value = DateUtils.formatDate(d, fieldInfo.getStr("FIELD_CONFIGINFO"));
                }
            }
        }else if("DATETIME".equals(fieldType)){
            if(StringUtil.isNotEmpty(fieldInfo.getStr("FIELD_CONFIGINFO")) && StringUtil.isNotEmpty(value)){
                Date d= DateUtils.getDate(value, DateUtils.DAFAULT_DATETIME_FORMAT);
                if(d!=null) {
                    value = DateUtils.formatDate(d, fieldInfo.getStr("FIELD_CONFIGINFO"));
                }
            }
        }else if("MOREFIELD".equals(fieldType)){
            Set<Map.Entry<String,String>> ddSet=new HashSet<>();
            ddSet.addAll(OfficeUtil.getDynaMap(dynaBean).entrySet());
            value= StringUtil.parseKeyWord(configInfo,ddSet);
        }else if("WFDATA".equals(fieldType)){
            value=dynaBean.getStr("WF_"+fieldInfo.getStr("FIELD_CONFIGINFO"),"");
        }
        if(StringUtil.isEmpty(value) && StringUtil.isNotEmpty(fieldInfo.getStr("FIELD_VALUE"))){
            value=fieldInfo.getStr("FIELD_VALUE","");
        }
        return value;
    }
}
